{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## How to use few-shot prompting with tool calling\n",
        "\n",
        "```{=mdx}\n",
        ":::info Prerequisites\n",
        "\n",
        "This guide assumes familiarity with the following concepts:\n",
        "\n",
        "- [Chat models](/docs/concepts/chat_models)\n",
        "- [LangChain Tools](/docs/concepts/tools)\n",
        "- [Tool calling](/docs/concepts/tool_calling)\n",
        "- [Passing tool outputs to chat models](/docs/how_to/tool_results_pass_to_model/)\n",
        "\n",
        ":::\n",
        "```\n",
        "\n",
        "For more complex tool use it's very useful to add few-shot examples to the prompt. We can do this by adding `AIMessages` with `ToolCalls` and corresponding `ToolMessages` to our prompt.\n",
        "\n",
        "First define a model and a calculator tool:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {},
      "outputs": [],
      "source": [
        "import { tool } from \"@langchain/core/tools\";\n",
        "import { z } from \"zod\";\n",
        "import { ChatOpenAI } from \"@langchain/openai\";\n",
        "\n",
        "const llm = new ChatOpenAI({ model: \"gpt-4o\", temperature: 0, })\n",
        "\n",
        "/**\n",
        " * Note that the descriptions here are crucial, as they will be passed along\n",
        " * to the model along with the class name.\n",
        " */\n",
        "const calculatorSchema = z.object({\n",
        "  operation: z\n",
        "    .enum([\"add\", \"subtract\", \"multiply\", \"divide\"])\n",
        "    .describe(\"The type of operation to execute.\"),\n",
        "  number1: z.number().describe(\"The first number to operate on.\"),\n",
        "  number2: z.number().describe(\"The second number to operate on.\"),\n",
        "});\n",
        "\n",
        "const calculatorTool = tool(async ({ operation, number1, number2 }) => {\n",
        "  // Functions must return strings\n",
        "  if (operation === \"add\") {\n",
        "    return `${number1 + number2}`;\n",
        "  } else if (operation === \"subtract\") {\n",
        "    return `${number1 - number2}`;\n",
        "  } else if (operation === \"multiply\") {\n",
        "    return `${number1 * number2}`;\n",
        "  } else if (operation === \"divide\") {\n",
        "    return `${number1 / number2}`;\n",
        "  } else {\n",
        "    throw new Error(\"Invalid operation.\");\n",
        "  }\n",
        "}, {\n",
        "  name: \"calculator\",\n",
        "  description: \"Can perform mathematical operations.\",\n",
        "  schema: calculatorSchema,\n",
        "});\n",
        "\n",
        "const llmWithTools = llm.bindTools([calculatorTool]);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Our calculator can handle common addition, subtraction, multiplication, and division. But what happens if we ask about a new mathematical operator, `🦜`?\n",
        "\n",
        "Let's see what happens when we use it naively:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "[\n",
            "  {\n",
            "    name: 'calculator',\n",
            "    args: { operation: 'multiply', number1: 3, number2: 12 },\n",
            "    type: 'tool_call',\n",
            "    id: 'call_I0oQGmdESpIgcf91ej30p9aR'\n",
            "  }\n",
            "]\n"
          ]
        }
      ],
      "source": [
        "const res = await llmWithTools.invoke(\"What is 3 🦜 12\");\n",
        "\n",
        "console.log(res.content);\n",
        "console.log(res.tool_calls);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "It doesn't quite know how to interpret `🦜` as an operation, and it defaults to `multiply`. Now, let's try giving it some examples in the form of a manufactured messages to steer it towards `divide`:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[\n",
            "  {\n",
            "    name: 'calculator',\n",
            "    args: { number1: 3, number2: 12, operation: 'divide' },\n",
            "    type: 'tool_call',\n",
            "    id: 'call_O6M4yDaA6s8oDqs2Zfl7TZAp'\n",
            "  }\n",
            "]\n"
          ]
        }
      ],
      "source": [
        "import { HumanMessage, AIMessage, ToolMessage } from \"@langchain/core/messages\";\n",
        "\n",
        "const res = await llmWithTools.invoke([\n",
        "  new HumanMessage(\"What is 333382 🦜 1932?\"),\n",
        "  new AIMessage({\n",
        "    content: \"The 🦜 operator is shorthand for division, so we call the divide tool.\",\n",
        "    tool_calls: [{\n",
        "      id: \"12345\",\n",
        "      name: \"calculator\",\n",
        "      args: {\n",
        "        number1: 333382,\n",
        "        number2: 1932,\n",
        "        operation: \"divide\",\n",
        "      }\n",
        "    }]\n",
        "  }),\n",
        "  new ToolMessage({\n",
        "    tool_call_id: \"12345\",\n",
        "    content: \"The answer is 172.558.\"\n",
        "  }),\n",
        "  new AIMessage(\"The answer is 172.558.\"),\n",
        "  new HumanMessage(\"What is 6 🦜 2?\"),\n",
        "  new AIMessage({\n",
        "    content: \"The 🦜 operator is shorthand for division, so we call the divide tool.\",\n",
        "    tool_calls: [{\n",
        "      id: \"54321\",\n",
        "      name: \"calculator\",\n",
        "      args: {\n",
        "        number1: 6,\n",
        "        number2: 2,\n",
        "        operation: \"divide\",\n",
        "      }\n",
        "    }]\n",
        "  }),\n",
        "  new ToolMessage({\n",
        "    tool_call_id: \"54321\",\n",
        "    content: \"The answer is 3.\"\n",
        "  }),\n",
        "  new AIMessage(\"The answer is 3.\"),\n",
        "  new HumanMessage(\"What is 3 🦜 12?\")\n",
        "]);\n",
        "\n",
        "console.log(res.tool_calls);"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "And we can see that it now equates `🦜` with the `divide` operation in the correct way!\n",
        "\n",
        "## Related\n",
        "\n",
        "- Stream [tool calls](/docs/how_to/tool_streaming/)\n",
        "- Pass [runtime values to tools](/docs/how_to/tool_runtime)\n",
        "- Getting [structured outputs](/docs/how_to/structured_output/) from models"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "TypeScript",
      "language": "typescript",
      "name": "tslab"
    },
    "language_info": {
      "codemirror_mode": {
        "mode": "typescript",
        "name": "javascript",
        "typescript": true
      },
      "file_extension": ".ts",
      "mimetype": "text/typescript",
      "name": "typescript",
      "version": "3.7.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}
